﻿using System;
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OpenFileTransfer.Wpf.WebSocketServer.Commands;
using OpenFileTransfer.Wpf.WebSocketServer.Server;
using SuperSocket;
using SuperSocket.Command;
using SuperSocket.ProtoBase;
using SuperSocket.WebSocket.Server;
using Unity;
using Unity.Microsoft.DependencyInjection;

namespace OpenFileTransfer.Wpf.Services
{
    public class WebSocketServerService : IWebSocketServerService
    {
        private IHost? _host;

        private readonly ILogService _logService;
        private readonly IConfigService _configService;
        private readonly IUnityContainer _container;

        public WebSocketServerService(
            ILogService logService,
            IConfigService configService,
            IUnityContainer container
        )
        {
            _logService = logService;
            _configService = configService;
            _container = container;
        }

        public void Startup()
        {
            try
            {
                _host = WebSocketHostBuilder.Create()
                    .UseCommand<StringPackageInfo, StringPackageConverter>(commandOptions =>
                    {
                        //注册命令
                        commandOptions.AddCommand<HeartbeatCommand>();
                    })
                    .UseSession<MySession>()
                    .UseInProcSessionContainer()
                    .UseMiddleware<MyMiddleware>()
                    // ReSharper disable once UnusedParameter.Local
                    .ConfigureAppConfiguration((hostBuilderContext, configurationBuilder) =>
                    {
                        var port = _configService.WebSocketServerInfo.Port;
                        configurationBuilder.AddInMemoryCollection(new Dictionary<string, string>
                        {
                            { "serverOptions:name", "MyServer" },
                            { "serverOptions:listeners:0:ip", "Any" },
                            { "serverOptions:listeners:0:port", $"{port}" },
                            //{"serverOptions:listeners:0:maxRequestLength", $"{1024 * 1024}"}
                        });
                    })
                    //使用IOC容器Unity
                    .UseUnityServiceProvider(_container)
                    // ReSharper disable once UnusedParameter.Local
                    .ConfigureLogging((hostCtx, loggingBuilder) =>
                    {
                        //添加控制台输出
                        loggingBuilder.AddConsole();
                    })
                    .Build();
            }
            catch (Exception e)
            {
                _logService.Error($"[WebSocketServerService] Create host failed: {e.Message}");
            }

            try
            {
                _host?.StartAsync().GetAwaiter();
            }
            catch (Exception e)
            {
                _logService.Error($"[SocketServerService] Startup failed: {e.Message}");
            }
        }

        public void Shutdown()
        {
            try
            {
                _host?.StopAsync().GetAwaiter().GetResult();
            }
            catch (Exception e)
            {
                _logService.Error($"[SocketServerService] Shutdown failed: {e.Message}.");
            }
            finally
            {
                _host?.Dispose();
            }
        }
    }
}
